//
//  DataModal.m
//  myp1
//
//  Created by go2matrix on 13-10-29.
//  Copyright (c) 2013年 go2matrix. All rights reserved.
//

#import "DataModal.h"
#import "Database.h"
#import "Global.h"
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"


@interface DataModal (){
    NSURLSession *_session;
    int count;
}

@end
@implementation DataModal
#pragma mark -
#pragma mark 单例模式
+ (DataModal *)instance  {
    static DataModal *instance;
    
    @synchronized(self) {
        if(!instance) {
            instance = [[DataModal alloc] init];
        }
    }
    return instance;
}
-(id)init{
    if (self = [super init]){
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        _session = [NSURLSession sessionWithConfiguration:configuration];
        count =0;


    }
    return self;
}
/*
 
 
 */
-(NSDictionary *)checkModal:(NSObject <DataModalProtocol>*)modal{
    NSDictionary *dic;
    count = count +1;
    //执行modal之前检查参数
    
        SEL selectorModalUrl = NSSelectorFromString(@"modalUrl");
        if (![modal respondsToSelector:selectorModalUrl] ){
            NSException *e = [NSException
                              exceptionWithName:@"无法执行modal"
                              reason:@"没有设置modalUrl"
                              userInfo:nil];
            @throw e;
        }
        SEL setSelector = NSSelectorFromString(@"processSuccess:");
        if (![modal respondsToSelector:setSelector] ){
            NSException *e = [NSException
                              exceptionWithName:@"无法执行modal"
                              reason:@"没有设置processSuccess"
                              userInfo:nil];
            @throw e;
        }
        dic = [modal modalUrl];

    return dic;
}




-(void)executeModal:(NSObject <DataModalProtocol>*)modal withhud:(BOOL)withhud completion:(void (^)(NSDictionary *data))completionHandler
            failure:(void(^)())failureHandler{
    @try {

       NSDictionary *dic=[self checkModal:modal];
        NSString *urlString = [dic valueForKey:@"url"];
        NSString *method =[dic valueForKey:@"method"];
        
        
        
        
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:urlString ] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
        [request setHTTPMethod:method];
        if ([method isEqualToString:@"POST" ]){
           NSString *postdata =[dic valueForKey:@"postdata"];
           NSError *error = nil;
           //将data1转换成json发送到服务器
           NSData *contentdata = [NSJSONSerialization dataWithJSONObject:postdata
                                                              options:NSJSONWritingPrettyPrinted
                                                                error:&error];
           [request setHTTPBody:contentdata];
        
        }
        NSURLSessionDataTask *dataTask = [_session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            if ([modal isKindOfClass:[DataModalBasic class]]){
                dispatch_async(dispatch_get_main_queue(), ^{
                    DataModalBasic *d = (DataModalBasic *)modal;
                    MBProgressHUD *hud = (MBProgressHUD *)(d.hud);
                    [hud hide:NO ];
                });
                
            }
            if (!error) {
                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                if (httpResponse.statusCode == 200) {
                    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                    NSData *data1 = [string dataUsingEncoding:NSUTF8StringEncoding];
                    //                NSRange range = NSMakeRange(0,[string length]-2);//去掉末尾的/r/n
                    //                NSData *backdata = [[string substringWithRange:range] dataUsingEncoding:NSUTF8StringEncoding];
                    NSError *error = nil;
                    NSDictionary *results = data1 ? [NSJSONSerialization JSONObjectWithData:data1 options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error] : nil;
                    //json转换
                    if (error) {
                        NSLog(@"[%@ %@] JSON error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error.localizedDescription);
                        NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                        
                        NSDictionary *dic = @{@"message":@"请求失败"};
                        SEL failSelector = sel_registerName("processFailed:datamodal:");
                        if ([self.delegate respondsToSelector:failSelector]){
                            [self.delegate performSelector:failSelector withObject:dic withObject:self];
                        }
                        return;
                    }
                   
                    //如果要执行的modal设置了delegate
                    [modal processSuccess:results];
                    if (completionHandler){
                        completionHandler(results);
                    }
                    
                    
                    
                }
            } else {
                if (failureHandler != nil){
                    failureHandler();
                } else {

                dispatch_async(dispatch_get_main_queue(), ^{
                    [[Global instance] showMessageDelay:@"请求失败"];
                });
                }
            }
            
        }];
        
        
        if (withhud && ([modal isKindOfClass:[DataModalBasic class]])){
            DataModalBasic *m = (DataModalBasic *)modal;
            UIWindow *window  = [[UIApplication sharedApplication] keyWindow];
            m.hasHud = withhud;
            m.hud = [[MBProgressHUD alloc] initWithView:window ];
            [window addSubview:(MBProgressHUD *)m.hud];
            
            MBProgressHUD *hud = (MBProgressHUD *)(m.hud);
            
            hud.delegate = self;
            hud.labelText = @"正在载入";
            [hud show:YES];
        }
        [dataTask resume];
    
    }
    @catch (NSException *exception)//捕获抛出的异常
    {
        [[Global instance] showMessageDelay:exception.reason];
        
        return;
    }
}

-(void)execute:(NSObject <DataModalProtocol>*)modal withhud:(BOOL)withhud{
    @try {
        
        [self executeModal:modal withhud:withhud completion:nil failure:nil];

    }
    @catch (NSException *exception)//捕获抛出的异常
    {
        [[Global instance] showMessageDelay:exception.reason];
        
        return;
    }


  
}
#pragma mark -
#pragma mark MBProgressHUDDelegate methods

- (void)hudWasHidden:(MBProgressHUD *)hud {
    // Remove HUD from screen when the HUD was hidded
    [hud removeFromSuperview];
    hud = nil;
}


//Dictionary复制
+(void) copyDictionary:(NSDictionary *)dict toItem:(NSObject *)object{
    NSArray *keys;
    NSInteger i, count;
    id key, value;
    
    keys = [dict allKeys];
    count = [keys count];
    for (i = 0; i < count; i++)
    {
        key = [keys objectAtIndex: i];
        value = [dict objectForKey: key];
        NSLog (@"Key: %@ for value: %@", key, value);
        NSString *method =[NSString stringWithFormat:@"set%@:",[key capitalizedString]];
        SEL sel = NSSelectorFromString(method); // 指定action
        if ((value!=[NSNull null])&&([(NSObject *)object respondsToSelector:sel])){
            [(NSObject *)object performSelector:sel withObject:value];
        }
        
    }
}



#pragma mark 删除数据
-(void )deleteObject :(NSManagedObject *)object{
    [self.managedObjectContext  deleteObject:object];
    NSError *error;
    [self.managedObjectContext save:&error];
    

}
#pragma mark 执行数据库查询
-(void )deleteEntity :(NSString *)entityName  whereString:(NSString *)whereString{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // 设置表名
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    if (![whereString isEqualToString:@""]){
        NSPredicate *predicate = [NSPredicate predicateWithFormat:whereString];
        [fetchRequest setPredicate:predicate];
    }
    NSError *error;
    NSArray *array =  [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    for (int i=0;i<[array count];i++){
        [self.managedObjectContext  deleteObject:[array objectAtIndex:i]];
    }
    [self.managedObjectContext save:&error];
}

#pragma mark 执行数据库查询
//查询distinct
-(NSArray *)queryUniqueData :(NSString *)entityName fieldname:(NSString *)fieldname{

  NSFetchRequest *request = [[NSFetchRequest alloc] init];
    // 设置表名
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.managedObjectContext];
  [request setEntity:entity];
  [request setResultType:NSDictionaryResultType];
  [request setReturnsDistinctResults:YES];
  [request setPropertiesToFetch:@[fieldname]];

   // Execute the fetch.
   NSError *error;

   NSArray *objects = [self.managedObjectContext executeFetchRequest:request error:&error];
   return objects;
}
//查询distinct
-(NSArray *)queryUniqueData :(NSString *)entityName fieldname:(NSString *)fieldname orderBy:(NSString *)order{
    
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    // 设置表名
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.managedObjectContext];
    [request setEntity:entity];
    [request setResultType:NSDictionaryResultType];
    [request setReturnsDistinctResults:YES];
    [request setPropertiesToFetch:@[fieldname]];
    NSSortDescriptor *sort=[NSSortDescriptor sortDescriptorWithKey:order ascending:NO];
    request.sortDescriptors=@[sort];

    // Execute the fetch.
    NSError *error;
    NSArray *objects = [self.managedObjectContext executeFetchRequest:request error:&error];
    return objects;
}

#pragma mark 执行数据库查询
-(NSArray *)queryData :(NSString *)entityName whereString:(NSString *)whereString{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // 设置表名
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    if (![whereString isEqualToString:@""]){
        NSPredicate *predicate = [NSPredicate predicateWithFormat:whereString];
        [fetchRequest setPredicate:predicate];
    }
    
    NSError *error;
    NSArray *array =  [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    return array;
}
#pragma mark 执行数据库查询
-(NSArray *)queryData :(NSString *)entityName whereString:(NSString *)whereString order:(NSString *)order ascending:(BOOL)ascending{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // 设置表名
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    if (![whereString isEqualToString:@""]){
        NSPredicate *predicate = [NSPredicate predicateWithFormat:whereString];
        [fetchRequest setPredicate:predicate];
    }
    NSSortDescriptor *sort=[NSSortDescriptor sortDescriptorWithKey:order ascending:ascending];
    fetchRequest.sortDescriptors=@[sort];

    NSError *error;
    NSArray *array =  [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    return array;
}


#pragma mark 新增一条数据库纪录
-(NSManagedObject *)createNewItem :(NSString *)entityName {
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:entityName  inManagedObjectContext:self.managedObjectContext];
    return newManagedObject;
}

- (NSManagedObjectContext *)managedObjectContext{
    return [Database instance].managedObjectContext;
}

+(id) createDataModal:(NSString *)className{
    /*
    NSObject * c1 = [[NSClassFromString(className) alloc] init];
    if (!c1){
        NSString *msg =[ NSString stringWithFormat:@"创建数据模型失败,可能Build Phases中没有包含%@",className ];
        @throw([NSException exceptionWithName:msg reason:msg userInfo:nil]);
    }
    return c1;
     */
    return [[DataModal alloc] init];
}
@end
@implementation DataModalBasic


@end
